package cn.virens.common.oauth.annotations.config;

import cn.virens.common.oauth.annotations.handler.VirAuthAnnotationSource;
import cn.virens.common.oauth.annotations.handler.VirAuthMethodInterceptor;
import cn.virens.common.oauth.annotations.handler.VirAuthMethodPointcutAdvisor;
import cn.virens.common.spring.annotations.config.VirAbstractImportAware;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.core.Ordered;

import java.lang.annotation.Annotation;

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class VirAuthConfiguration extends VirAbstractImportAware {

    @Bean("virAuthAnnotationSource")
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public VirAuthAnnotationSource virAuthAnnotationSource() throws Exception {
        return new VirAuthAnnotationSource();
    }

    @Bean("virAuthMethodInterceptor")
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public VirAuthMethodInterceptor virAuthMethodInterceptor(//
                                                             @Qualifier("virAuthAnnotationSource") VirAuthAnnotationSource virAuthAnnotationSource//
    ) throws Exception {
        VirAuthMethodInterceptor interceptor = new VirAuthMethodInterceptor();
        interceptor.setAnnotationSource(virAuthAnnotationSource);

        return interceptor;
    }

    @Bean("virAuthMethodPointcutAdvisor")
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public VirAuthMethodPointcutAdvisor virAuthMethodPointcutAdvisor(//
                                                                     @Qualifier("virAuthAnnotationSource") VirAuthAnnotationSource virAuthAnnotationSource,//
                                                                     @Qualifier("virAuthMethodInterceptor") VirAuthMethodInterceptor virAuthMethodInterceptor//
    ) throws Exception {
        VirAuthMethodPointcutAdvisor advisor = new VirAuthMethodPointcutAdvisor();
        advisor.setOrder(getInteger("order", Ordered.LOWEST_PRECEDENCE));
        advisor.setAnnotationSource(virAuthAnnotationSource);
        advisor.setAdvice(virAuthMethodInterceptor);

        return advisor;
    }

    @Override
    protected Class<? extends Annotation> getAnnotationClass() {
        return EnableVirAuth.class;
    }

}
